/**
 * Copyright 2018-2019 jianggujin (www.jianggujin.com).
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *      http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.jianggujin.modulelink.action;

import java.util.Collection;
import java.util.Set;

import com.jianggujin.modulelink.config.JModuleConfig;
import com.jianggujin.modulelink.exception.JActionNotFoundException;
import com.jianggujin.modulelink.module.JModule;
import com.jianggujin.modulelink.module.JModuleState;

/**
 * 模块上下文
 * 
 * @author jianggujin
 *
 */
public class JModuleContext {
    private static ThreadLocal<JModuleCounterWrapper> local = new ThreadLocal<JModuleCounterWrapper>();

    /**
     * 设置模块
     * 
     * @param module 模块
     */
    protected static void set(JModule<?> module) {
        JModuleCounterWrapper wrapper = local.get();
        if (wrapper != null && wrapper.module == module) {
            wrapper.counter++;
            return;
        }
        local.set(new JModuleCounterWrapper(module));
    }

    /**
     * 获得模块
     * 
     * @return 模块对象
     */
    private static JModule<?> getModule() {
        return local.get().module;
    }

    /**
     * 获得模块配置
     * 
     * @return
     */
    public static JModuleConfig getModuleConfig() {
        return getModule().getModuleConfig();
    }

    /**
     * 获取全部的Action名称
     * 
     * @return 全部的Action名称
     */
    public static Set<String> getActionNames() {
        return getModule().getActionNames();
    }

    /**
     * 获取全部的Action
     * 
     * @return 全部的Action
     */
    public static Collection<Object> getActions() {
        return getModule().getActions();
    }

    /**
     * 获取全部的Action
     * 
     * @return 全部的Action
     */
    public static Collection<JActionWrapper> getActionWrappers() {
        return getModule().getActionWrappers();
    }

    /**
     * 获取默认的Action名称
     * 
     * @return 默认的Action名称
     * @throws JActionNotFoundException 未找到Action异常
     */
    public static String getDefaultActionName() {
        return getModule().getDefaultActionName();
    }

    /**
     * 获得默认的Action
     * 
     * @return 默认的Action
     */
    public static Object getDefaultAction() {
        return getModule().getDefaultAction();
    }

    /**
     * 获得默认的Action
     * 
     * @return 默认的Action
     */
    public static JActionWrapper getDefaultActionWrapper() {
        return getModule().getDefaultActionWrapper();
    }

    /**
     * 获取默认的Action名称
     * 
     * @return 不存在默认名称返回null
     */
    public static String optDefaultActionName() {
        return getModule().optDefaultActionName();
    }

    /**
     * 获得默认的Action
     * 
     * @return 默认的Action，不存在则返回null
     */
    public static Object optDefaultAction() {
        return getModule().optDefaultAction();
    }

    /**
     * 获得默认的Action
     * 
     * @return 默认的Action，不存在则返回null
     */
    public static JActionWrapper optDefaultActionWrapper() {
        return getModule().optDefaultActionWrapper();
    }

    /**
     * 执行指定的Action
     * 
     * @param actionName action名称
     * @param in         执行Action的入参
     * @return 执行结果
     * @throws JActionNotFoundException 未找到Action异常
     */
    public static Object doAction(String actionName, Object in) {
        return getModule().invokeAction(actionName, in);
    }

    /**
     * 是否存在Action
     * 
     * @param name action名称
     * @return 存在则返回true
     */
    public static boolean hasAction(String name) {
        return getModule().hasAction(name);
    }

    /**
     * 通过名称获得Action
     * 
     * @param name action名称
     * @return Action
     * @throws JActionNotFoundException 未找到Action异常
     */
    public static Object getAction(String name) {
        return getModule().getAction(name);
    }

    /**
     * 通过名称获得Action
     * 
     * @param name action名称
     * @return Action
     * @throws JActionNotFoundException 未找到Action异常
     */
    public static JActionWrapper getActionWrapper(String name) {
        return getModule().getActionWrapper(name);
    }

    /**
     * 通过名称获得Action
     * 
     * @param name action名称
     * @return 不存在则返回null
     */
    public static Object optAction(String name) {
        return getModule().optAction(name);
    }

    /**
     * 通过名称获得Action
     * 
     * @param name action名称
     * @return 不存在则返回null
     */
    public static JActionWrapper optActionWrapper(String name) {
        return getModule().optActionWrapper(name);
    }

    /**
     * 执行默认的Action
     * 
     * @param in 执行Action的入参
     * @return 执行结果
     * @throws JActionNotFoundException 未找到Action异常
     */
    public static Object doDefaultAction(Object in) {
        return getModule().invokeDefaultAction(in);
    }

    /**
     * 是否有默认Action
     * 
     * @return 存在着而返回true
     */
    public static boolean hasDefaultAction() {
        return getModule().hasDefaultAction();
    }

    /**
     * 是否为激活状态
     * 
     * @return
     */
    public static boolean isActive() {
        return JModuleState.ACTIVED == getModule().getModuleState();
    }

    /**
     * 清除
     */
    protected static void clear() {
        JModuleCounterWrapper wrapper = local.get();
        if (wrapper != null) {
            wrapper.counter--;
            if (wrapper.counter < 1) {
                local.remove();
            }
        }
    }

    static class JModuleCounterWrapper {
        JModule<?> module;
        int counter;

        private JModuleCounterWrapper(JModule<?> module) {
            this.module = module;
            this.counter = 1;
        }
    }
}
